package com.zxtech.zzm.zxmonitorsocket

import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.IBinder
import android.util.Log
import com.zxtech.zzm.core.util.CodecUtil
import com.zxtech.zzm.core.util.DeviceUtil
import com.zxtech.zzm.core.util.LoggerUtil
import com.zxtech.zzm.zxmonitorsocket.SocketPackageSend.Builder
import com.zxtech.zzm.zxmonitorsocket.thread.HeartBeatThread
import com.zxtech.zzm.zxmonitorsocket.thread.MonitorThread
import com.zxtech.zzm.zxmonitorsocket.thread.ResponseThread
import com.zxtech.zzm.zxmonitorsocket.thread.ThreadPoolManager
import com.zxtech.zzm.zxmonitorsocket.util.SocketLoggerUtil
import java.io.InputStream
import java.io.OutputStream
import java.net.InetSocketAddress
import java.net.Socket
import java.net.SocketAddress

class ZXMonitorSocketService : Service() {
  override fun onBind(intent: Intent?): IBinder? {
    return null
  }

  override fun onCreate() {
    super.onCreate()
    context = this
    ThreadPoolManager.instance?.execute(MonitorThread())
    connectSocket()
  }

  companion object {
    var context: Context? = null
    private var clientis: InputStream? = null
    private var clientos: OutputStream? = null
    private var reconnect_count = 1
    var isConnected = false
    private var heartBeatThread: HeartBeatThread? = null
    private var responseThread: ResponseThread? = null
    var socket: Socket? = null
    fun sendPackage(builder: Builder) {
      Log.e(
        "zzm debug", " sendPackage : " + CodecUtil.formatHexString(
          builder.build().buildPackage()
        )
      )
      try {
        clientos?.write(
          builder.build()
            .buildPackage()
        )
        clientos?.flush()
      } catch (e: Exception) {
        e.printStackTrace()
      }
    }

    fun getHeartBeatThread(): HeartBeatThread? {
      if (heartBeatThread == null) {
        heartBeatThread = HeartBeatThread(socket!!)
      }
      return heartBeatThread
    }

    fun getResponseThread(): ResponseThread? {
      if (responseThread == null) {
        responseThread = ResponseThread(socket!!)
      }
      return responseThread
    }

    private fun stopSocketSerice() {
      try {
        //关闭Socket相关线程
        if (responseThread != null) {
          responseThread?.setStopFlag(true)
          responseThread?.interrupt()
          responseThread = null
        }
        if (heartBeatThread != null) {
          heartBeatThread?.setStopFlag(true)
          heartBeatThread?.interrupt()
          heartBeatThread = null
        }
        //关闭Socket和输入输出流
        if (socket != null) {
          socket?.shutdownInput()
          socket?.shutdownOutput()
          socket?.close()
          socket = null
        }
      } catch (e: java.lang.Exception) {
        e.printStackTrace()
      }
    }

    fun reconnect() {
      SocketLoggerUtil.logSocket("SocketService.reconnect Socket重连中", LoggerUtil.LOGGERUTIL_WARNING)
      stopSocketSerice()
      connectSocket()
    }

    private fun connectSocket() {
      val t = Thread {
        try {
          socket = Socket()
          val sa: SocketAddress =
            InetSocketAddress(Config.SOCKET_SERVER_IP, Config.SOCKET_SERVER_PORT)
          socket!!.connect(sa, 3000)
          clientis = socket!!.getInputStream()
          clientos = socket!!.getOutputStream()
          isConnected = true
        } catch (e: Exception) {
          e.printStackTrace()
          SocketLoggerUtil.logSocket("无法建立ZXMonitorSocket链接", LoggerUtil.LOGGERUTIL_ERROR)
          isConnected = false
        }
        if (isConnected) {
          reconnect_count = 1
          SocketLoggerUtil.logSocket("ZXMonitorSocket链接成功！")
          registerSocket()
          ThreadPoolManager.instance?.execute(getResponseThread())
        }
      }
      t.name = "zxmontior_socket_connect"
      ThreadPoolManager.instance?.execute(t)
    }

    /**
     * 《面向终端设备的socket协议》
     * com.zxtech.zzm.zxtablet版本名|
     * com.zxtech.zzm.zxtablet版本号|
     * com.zxtech.zzm.zxmonitor版本名|
     * com.zxtech.zzm.zxmonitor版本号|
     * com.zxtech.product.factory版本名|
     * com.zxtech.product.factory版本号|
     * org.linphone版本名|
     * org.linphone版本号|
     * android ROM版本名|
     * android ROM版本号|
     * android SDK版本号|
     * 信号强度（模块CSQ值）|
     * IMSI|
     * 终端设备类型（详见终端设备类型描述）
     */
    private fun registerSocket() {
      val t = Thread {
        val data = " | | | | | | | | | | | | | "
        val bytes = ByteArray(data.toByteArray().size + 1)
        System.arraycopy(data.toByteArray(), 0, bytes, 0, data.toByteArray().size)
        bytes[data.toByteArray().size] = 0x01
        val length = bytes.size.toShort()
        val b: ByteArray = CodecUtil.short2bytes(length)
        val builder = Builder()
        builder.setPackageLength(b[0], b[1])
          .setType(0x00.toByte())
          .setIdBytes(
            DeviceUtil.getTerminalID()
              .toByteArray()
          )
          .setData(bytes)
        sendPackage(builder)
      }
      t.name = "zxmonitor_socket_register"
      ThreadPoolManager.instance?.execute(t)
    }
  }

  override fun onDestroy() {
    super.onDestroy()
    stopSocketSerice()
  }
}



